/**
 * 
 */
package com.dalonedrau.jogl.opengl.ui;

import java.awt.Dimension;

import com.ahq.main.H1SelectionBorder;
import com.dalonedrau.jogl.engine.ProjectConstants;
import com.dalonedrau.jogl.opengl.GameFont;
import com.dalonedrau.jogl.opengl.sprite.BasicSpriteObject;
import com.dalonedrau.jogl.opengl.sprite.SpriteBase;
import com.dalonedrau.jogl.opengl.sprite.SpriteImageObject;
import com.dalonedrau.jogl.opengl.sprite.SpriteImageObjectFactory;
import com.dalonedrau.jogl.opengl.ui.border.Abstract8ImageBorderWithLinesAndGradient;
import com.dalonedrau.jogl.opengl.ui.border.EmptyBorder;
import com.dalonedrau.jogl.opengl.ui.border.GuiBorder;
import com.dalonedrau.jogl.opengl.ui.menu.MenuItem;
import com.dalonedrau.pool.PooledStringBuilder;
import com.dalonedrau.pool.StringBuilderPool;

/**
 * Factory class for producing standardized UI widgets.
 * @author Donald
 */
public final class UIFactory {
	/** the one and only instance of the <code>UIFactory</code> class. */
	private static UIFactory	instance;
	/**
	 * UIFactory Gives access to the singleton instance of {@link UIFactory}.
	 * @return {@link UIFactory}
	 */
	public static UIFactory getInstance() {
		if (UIFactory.instance == null) {
			UIFactory.instance = new UIFactory();
		}
		return UIFactory.instance;
	}
	/** Hidden constructor. */
	private UIFactory() {}
	/**
	 * Gets the maximum size for a character in a specific font.
	 * @param font the name of the font
	 * @return {@link Dimension}
	 * @throws Exception if an error occurs
	 */
	public Dimension getFontCharacterMetrics(final int fontId)
			throws Exception {
		return GameFont.getInstance().getFontById(fontId).getMaxCharMetrics();
	}
	/**
	 * Gets the maximum size for a character in a specific font.
	 * @param font the name of the font
	 * @return {@link Dimension}
	 * @throws Exception if an error occurs
	 */
	public Dimension getFontCharacterMetrics(final String font)
			throws Exception {
		return GameFont.getInstance().getFontByName(font).getMaxCharMetrics();
	}
	/**
	 * Gets the maximum size for a character in the H1 font.
	 * @return {@link Dimension}
	 * @throws Exception if an error occurs
	 */
	public Dimension getH1FontCharacterMetrics() throws Exception {
		String font = ProjectConstants.getInstance().getFontH1();
		return GameFont.getInstance().getFontByName(font).getMaxCharMetrics();
	}
	/**
	 * Gets a blank spacer label intended to create space between elements.
	 * @param width the spacer's width
	 * @param height the spacer's height
	 * @return {@link Label}
	 */
	public Label getSpacer(final int width, final int height) {
		Label l = UIFactory.getInstance().getStandardH1Label("");
		l.setBorder(new EmptyBorder(height, width, 0, 0));
		return l;
	}
	/**
	 * Gets a standard button item.
	 * @param text the button's text
	 * @return {@link Button}
	 */
	public Button getStandardButton(final char[] text) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		for (int i = 0; i < text.length; i++) {
			sb.append(text[i]);
		}
		Button button = getStandardButton(sb.toString());
		sb.returnToPool();
		return button;
	}
	/**
	 * Gets a standard button item.
	 * @param text the button's text
	 * @return {@link Button}
	 */
	public Button getStandardButton(final String text) {
		Button item = new Button(
				ProjectConstants.getInstance().getFontNormal(),
				text
				);
		item.setColor(ProjectConstants.getInstance().getDefaultFontColor());
		return item;
	}
	/**
	 * Gets a standard H1 button.
	 * @param text the button's text
	 * @return {@link Button}
	 */
	public Button getStandardH1Button(final char[] text) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		for (int i = 0; i < text.length; i++) {
			sb.append(text[i]);
		}
		Button button = getStandardH1Button(sb.toString());
		sb.returnToPool();
		return button;
	}
	/**
	 * Gets a standard H1 button.
	 * @param text the button's text
	 * @return {@link Button}
	 */
	public Button getStandardH1Button(final String text) {
		Button button = new Button(
				ProjectConstants.getInstance().getFontH1(),
				text
				);
		button.setColor(ProjectConstants.getInstance().getDefaultFontColor());
		button.setInactiveColor(
				ProjectConstants.getInstance().getInactiveFontColor());
		return button;
	}
	/**
	 * Gets a standard H1 label.
	 * @param text the label's text
	 * @return {@link Label}
	 */
	public Label getStandardH1Label(final char[] text) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		for (int i = 0; i < text.length; i++) {
			sb.append(text[i]);
		}
		Label label = getStandardH1Label(sb.toString());
		sb.returnToPool();
		return label;
	}
	/**
	 * Gets a standard H1 label.
	 * @param text the label's text
	 * @return {@link Label}
	 */
	public Label getStandardH1Label(final int text) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		sb.append(text);
		Label label = getStandardH1Label(sb.toString());
		sb.returnToPool();
		return label;
	}
	/**
	 * Gets a standard H1 label.
	 * @param text the label's text
	 * @return {@link Label}
	 */
	public Label getStandardH1Label(final String text) {
		return getStandardH1Label(text, false);
	}
	/**
	 * Gets a standard H1 label.
	 * @param text the label's text
	 * @param debug the flag indicating whether the Label needs debugging turned
	 *        on
	 * @return {@link Label}
	 */
	public Label getStandardH1Label(final String text, final boolean debug) {
		Label label = new Label(
				ProjectConstants.getInstance().getFontH1(),
				text,
				debug
				);
		label.setColor(ProjectConstants.getInstance().getDefaultFontColor());
		return label;
	}
	/**
	 * Gets a standard H1 label.
	 * @param text the label's text
	 * @return {@link Label}
	 */
	public SimpleScrollingTextWindow getStandardH1SimpleScrollingTextWindow(
			final String text, final int maxLines, final int maxChars) {
		return getStandardH1SimpleScrollingTextWindow(
				text, maxLines, maxChars, false);
	}
	/**
	 * Gets a standard H1 label.
	 * @param text the label's text
	 * @param debug the flag indicating whether the Label needs debugging turned
	 *        on
	 * @return {@link Label}
	 */
	public SimpleScrollingTextWindow getStandardH1SimpleScrollingTextWindow(
			final String text, final int maxLines, final int maxChars,
			final boolean debug) {
		SimpleScrollingTextWindow tw = new SimpleScrollingTextWindow(
				ProjectConstants.getInstance().getFontH1(),
				text,
				maxLines,
				maxChars,
				debug
				);
		tw.setColor(ProjectConstants.getInstance().getDefaultFontColor());
		return tw;
	}
	/**
	 * Gets a standard H1 button.
	 * @param text the button's text
	 * @return {@link Button}
	 */
	public Button getStandardH2Button(final char[] text) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		for (int i = 0; i < text.length; i++) {
			sb.append(text[i]);
		}
		Button button = getStandardH2Button(sb.toString());
		sb.returnToPool();
		return button;
	}
	/**
	 * Gets a standard H1 button.
	 * @param text the button's text
	 * @return {@link Button}
	 */
	public Button getStandardH2Button(final String text) {
		Button button = new Button(
				ProjectConstants.getInstance().getFontH2(),
				text
				);
		button.setColor(ProjectConstants.getInstance().getDefaultFontColor());
		button.setInactiveColor(
				ProjectConstants.getInstance().getInactiveFontColor());
		return button;
	}
	/**
	 * Gets a standard H2 label.
	 * @param text the label's text
	 * @return {@link Label}
	 */
	public Label getStandardH2Label(final char[] text) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		for (int i = 0; i < text.length; i++) {
			sb.append(text[i]);
		}
		Label label = getStandardH2Label(sb.toString());
		sb.returnToPool();
		return label;
	}
	/**
	 * Gets a standard H1 label.
	 * @param text the label's text
	 * @return {@link Label}
	 */
	public Label getStandardH2Label(final int text) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		sb.append(text);
		Label label = getStandardH2Label(sb.toString());
		sb.returnToPool();
		return label;
	}
	/**
	 * Gets a standard H2 label.
	 * @param text the label's text
	 * @return {@link Label}
	 */
	public Label getStandardH2Label(final String text) {
		Label label = new Label(
				ProjectConstants.getInstance().getFontH2(),
				text
				);
		label.setColor(ProjectConstants.getInstance().getDefaultFontColor());
		return label;
	}
	/**
	 * Gets a {@link Button} with an icon.
	 * @param imgRef the reference id for the icon image
	 * @return {@link Button}
	 * @throws Exception if an error occurs
	 */
	public Button getStandardImageButton(final int imgRef) throws Exception {
		SpriteBase sb = new BasicSpriteObject();
		SpriteImageObject img =
				SpriteImageObjectFactory.getInstance().getImageById(imgRef);
		sb.setImageRefId(img.getRefId());
		sb.setWidth(img.getWidth());
		sb.setHeight(img.getHeight());
		Button button = new Button(sb);
		sb = null;
		img = null;
		return button;
	}
	/**
	 * Gets a standard label.
	 * @param text the label's text
	 * @return {@link Label}
	 */
	public Label getStandardLabel(final char[] text) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		for (int i = 0; i < text.length; i++) {
			sb.append(text[i]);
		}
		Label label = getStandardLabel(sb.toString());
		sb.returnToPool();
		return label;
	}
	/**
	 * Gets a standard label.
	 * @param text the label's text
	 * @return {@link Label}
	 */
	public Label getStandardLabel(final int text) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		sb.append(text);
		Label label = getStandardLabel(sb.toString());
		sb.returnToPool();
		return label;
	}
	/**
	 * Gets a standard label.
	 * @param text the label's text
	 * @return {@link Label}
	 */
	public Label getStandardLabel(final String text) {
		return getStandardH1Label(text, false);
	}
	/**
	 * Gets a standard label.
	 * @param text the label's text
	 * @param debug the flag indicating whether the Label needs debugging turned
	 *        on
	 * @return {@link Label}
	 */
	public Label getStandardLabel(final String text, final boolean debug) {
		Label label = new Label(
				ProjectConstants.getInstance().getFontNormal(),
				text,
				debug
				);
		label.setColor(ProjectConstants.getInstance().getDefaultFontColor());
		return label;
	}
	/**
	 * Gets a standard menu item, with an arrow highlight.
	 * @param text the menu item's text
	 * @return {@link MenuItem}
	 */
	public MenuItem getStandardMenuItem(final String text) {
		MenuItem item = new MenuItem(
				ProjectConstants.getInstance().getFontH1(),
				text
				);
		item.setColor(ProjectConstants.getInstance().getDefaultFontColor());
		item.setAlignment(GuiComponent.CENTER, GuiComponent.CENTER);
		item.setHighlightBorder(new H1SelectionBorder());
		return item;
	}
	/**
	 * Gets a standard H1 button.
	 * @param text the button's text
	 * @return {@link Button}
	 */
	public Button getStandardTitleButton(final char[] text) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		for (int i = 0; i < text.length; i++) {
			sb.append(text[i]);
		}
		Button button = getStandardTitleButton(sb.toString());
		sb.returnToPool();
		return button;
	}
	/**
	 * Gets a standard H1 button.
	 * @param text the button's text
	 * @return {@link Button}
	 */
	public Button getStandardTitleButton(final String text) {
		Button button = new Button(
				ProjectConstants.getInstance().getFontTitle(),
				text
				);
		button.setColor(ProjectConstants.getInstance().getDefaultFontColor());
		button.setInactiveColor(
				ProjectConstants.getInstance().getInactiveFontColor());
		return button;
	}
	/**
	 * Gets a title label.
	 * @param text the label's text
	 * @return {@link Label}
	 */
	public Label getTitleLabel(final char[] text) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		for (int i = 0; i < text.length; i++) {
			sb.append(text[i]);
		}
		Label label = getTitleLabel(sb.toString());
		sb.returnToPool();
		return label;
	}
	/**
	 * Gets a title label.
	 * @param text the label's text
	 * @return {@link Label}
	 */
	public Label getTitleLabel(final int text) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		sb.append(text);
		Label label = getTitleLabel(sb.toString());
		sb.returnToPool();
		return label;
	}
	/**
	 * Gets a title label.
	 * @param text the label's text
	 * @return {@link Label}
	 */
	public Label getTitleLabel(final String text) {
		return getTitleLabel(text, false);
	}
	/**
	 * Gets a title label.
	 * @param text the label's text
	 * @param debug the flag indicating whether the Label needs debugging turned
	 *        on
	 * @return {@link Label}
	 */
	public Label getTitleLabel(final String text, final boolean debug) {
		Label label = new Label(
				ProjectConstants.getInstance().getFontTitle(),
				text,
				debug
				);
		label.setColor(ProjectConstants.getInstance().getDefaultFontColor());
		return label;
	}
	/**
	 * Gets a VX-Style dialog border, consisting of a series of border images,
	 * and a two-color gradient background with white lines beneath.
	 * @return {@link GuiBorder}
	 */
	public GuiBorder getVXStyleDialogBorder() {
		return new Abstract8ImageBorderWithLinesAndGradient(
				ProjectConstants.getInstance().getVXStyleDialogInsets(),
				ProjectConstants.getInstance().getVXStyleDialogBorderImages(),
				ProjectConstants.getInstance().getVXStyleDialogGradientTop(),
				ProjectConstants.getInstance().getVXStyleDialogGradientBottom(),
				ProjectConstants.getInstance().getVXStyleDialogXOffset(),
				ProjectConstants.getInstance().getVXStyleDialogYOffset());
	}
	/**
	 * Gets a VX-Style dialog border, consisting of a series of border images,
	 * and a two-color gradient background with white lines beneath.
	 * @return {@link GuiBorder}
	 */
	public GuiBorder getVXStyleSpeechBorder() {
		return new Abstract8ImageBorderWithLinesAndGradient(
				ProjectConstants.getInstance().getVXStyleSpeechInsets(),
				ProjectConstants.getInstance().getVXStyleSpeechBorderImages(),
				ProjectConstants.getInstance().getVXStyleSpeechGradientTop(),
				ProjectConstants.getInstance().getVXStyleSpeechGradientBottom(),
				ProjectConstants.getInstance().getVXStyleSpeechXOffset(),
				ProjectConstants.getInstance().getVXStyleSpeechYOffset());
	}
}
